/**
 * 
 */
package kr.or.smardi.smardi_AScan.Record.graph;

import java.text.*;
import java.util.*;
import android.content.*;
import android.graphics.*;
import android.graphics.Paint.*;
import android.util.*;
import android.view.*;

/**
 * @author Wenly
 * 
 */

public class Graph {
	
	String TAG = "A-Scan";
	boolean D = false;
	
	DisplayMetrics outMetrics = new DisplayMetrics();
	Window window;
	public Origin origin;
	public Size size;
	Context context;

	final float DEFAULT_ORI_X = 0; // 기본 원점 위치
	final float DEFAULT_ORI_Y = 50;

	final float DEFAULT_WIDTH = 600; // 기본 사이즈
	final float DEFAULT_HEIGHT = 300;
	
	int colorLine = 0;	//그래프 색
	int colorPoint = 0;
	
	AxisX axisX;	//축 관련된 변수 선언
	AxisY axisY;
	
	//Margin of top of graph
	int graphMarginTop = DPtoPX(10);
	
	ArrayList<ArrayList> arrayGraphData = new ArrayList<ArrayList>();
	ArrayList<Integer> arrayGraphColor = new ArrayList<Integer>();
	ArrayList<String> arrayGraphTitle = new ArrayList<String>();

	public int unitType = 0;	//단위를 나타내는 
	
	public Graph(Window window) {
		this.window = window;
		window.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

		origin = new Origin(DEFAULT_ORI_X, DEFAULT_ORI_Y);
		size = new Size(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		
		arrayGraphData = new ArrayList<ArrayList>();
		arrayGraphColor = new ArrayList<Integer>();
	}

	/**
	 * @param window
	 *            window
	 * @param width
	 *            그래프의 가로 길이
	 * @param height
	 *            그래프의 세로 길이
	 */
	public Graph(Window window, int width, int height) {
		this.window = window;
		window.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

		origin = new Origin(DEFAULT_ORI_X, DEFAULT_ORI_Y);
		size = new Size(width, height);
		
		arrayGraphData = new ArrayList<ArrayList>();
		arrayGraphColor = new ArrayList<Integer>();
	}
	
	public Graph(Window window,int ori_x, int ori_y, int width, int height, float minX, float maxX, float minY, float maxY) {
		this.window = window;
		window.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

		origin = new Origin(ori_x, ori_y);
		size = new Size(width, height);
		axisX = new AxisX();
		axisY = new AxisY();
		
		axisX.setMin(minX);
		axisX.setMax(maxX);
		axisY.setMin(minY);
		axisY.setMax(maxY);
		
		graphMarginTop = DPtoPX(10);
		arrayGraphData = new ArrayList<ArrayList>();
		arrayGraphColor = new ArrayList<Integer>();
	}

	/**
	 * @param window
	 *            window
	 * @param ori_x
	 *            원점의 x좌표
	 * @param ori_y
	 *            원점의 y좌표
	 * @param width
	 *            그래프의 가로 길이
	 * @param height
	 *            그래프의 세로 길이
	 */
	public Graph(Window window, int ori_x, int ori_y, int width, int height) {
		this.window = window;
		window.getWindowManager().getDefaultDisplay().getMetrics(outMetrics);

		origin = new Origin(ori_x, ori_y);
		size = new Size(width, height);
	}
	
	public Graph(int ori_x, int ori_y, int width, int height, float minX,
			float maxX, float minY, float maxY) {
		origin = new Origin(ori_x, ori_y);
		size = new Size(width, height);

		axisX = new AxisX();
		axisY = new AxisY();

		axisX.setMin(minX);
		axisX.setMax(maxX);
		axisY.setMin(minY);
		axisY.setMax(maxY);

		graphDatas = new ArrayList<GraphData>();
	}

	public class Origin {
		float x;
		float y;

		/**
		 * @param x unit: DP
		 * @param y unit: DP
		 */
		public Origin(float x, float y) {
			this.x = DPtoPX(x);
			this.y = DPtoPX(y);
			
			graphMarginTop = DPtoPX(10);
		}
	}

	public void setOrigin(float x, float y) {
		this.origin.x = x;
		this.origin.y = y;
	}

	public class Size {
		// 단위는 px
		float width;
		float height;

		/**
		 * @param _width
		 *            unit: DP
		 * @param _height
		 *            unit: DP
		 */
		public Size(float _width, float _height) {
			this.width = _width;
			this.height = _height;
		}
	}
	
	
	/**
	 * @author floro
	 * show: boolean
	 * labelBoxBorderColor: color
	 * position: "ne" or "nw" or "se" or "sw"
	 * margin: number of pixels or [x margin, y margin]
	 * backgroundColor: null or color
	 */
	public class Legend {
		private boolean show;
		private int labelBoxBorderColor;
		private String position;
		private int margin;
		private int backgroundColor;
		
		public Legend() {
			setShow(false);
			setLabelBoxBorderColor(Color.GRAY);
			setPosition("nw");
			setMargin(10);
			setBackgroundColor(Color.argb(125, 255, 255, 255));
		}

		void setShow(boolean show) {
			this.show = show;
		}

		boolean isShow() {
			return show;
		}

		void setLabelBoxBorderColor(int labelBoxBorderColor) {
			this.labelBoxBorderColor = labelBoxBorderColor;
		}

		int getLabelBoxBorderColor() {
			return labelBoxBorderColor;
		}

		void setPosition(String position) {
			this.position = position;
		}

		String getPosition() {
			return position;
		}

		void setMargin(int margin) {
			this.margin = margin;
		}

		int getMargin() {
			return margin;
		}

		void setBackgroundColor(int backgroundColor) {
			this.backgroundColor = backgroundColor;
		}

		int getBackgroundColor() {
			return backgroundColor;
		}
		
	}
	
	/**
	 * @author floro
	 * mode: null or "time"
	 * min: Float.NEGATIVE_INFINITY or number
	 * max: Float.POSITIVE_INFINITY or number
	 * autoscaleMargin: null or number
	 * 
	 * ticks: null or number or ticks array or (fn: range -> ticks array)
	 * tickSize: number or array
	 */
	public class AxisX {
		private String mode;
		private float min;
		private float max;
		private int autoscaleMargin;
		
		private ArrayList<Ticks> ticks;
		private int tickSize;
		
		public AxisX() {
			this.setMode(null);
			this.setMin(Float.NEGATIVE_INFINITY);
			this.setMax(Float.POSITIVE_INFINITY);
			this.setAutoscaleMargin(10);
			this.setTicks(null);
			this.setTickSize(0);
		}
		
		public String getMode() {
			return mode;
		}
		public void setMode(String mode) {
			this.mode = mode;
		}
		public float getMin() {
			return min;
		}
		public void setMin(float min) {
			this.min = min;
		}
		public float getMax() {
			return max;
		}
		public void setMax(float max) {
			this.max = max;
		}
		public int getAutoscaleMargin() {
			return autoscaleMargin;
		}
		/**
		 * @param autoscaleMargin DP 단위로 넣을 것
		 */
		public void setAutoscaleMargin(int autoscaleMargin) {
			this.autoscaleMargin = autoscaleMargin;
		}
		public ArrayList<Ticks> getTicks() {
			return ticks;
		}
		public void setTicks(ArrayList<Ticks> ticks) {
			this.ticks = ticks;
		}
		public int getTickSize() {
			return tickSize;
		}
		public void setTickSize(int tickSize) {
			this.tickSize = tickSize;
		}
	}
	
	/**
	 * @author floro
	 * mode: null or "time"
	 * min: Float.NEGATIVE_INFINITY or number
	 * max: Float.POSITIVE_INFINITY or number
	 * autoscaleMargin: null or number
	 * 
	 * ticks: null or number or ticks array or (fn: range -> ticks array)
	 * tickSize: number or array
	 */
	public class AxisY {
		private String mode;
		private float min;
		private float max;
		private int autoscaleMargin;
		
		private ArrayList<Ticks> ticks;
		private int tickSize;
		
		public AxisY() {
			this.setMode(null);
			this.setMin(Float.NEGATIVE_INFINITY);
			this.setMax(Float.POSITIVE_INFINITY);
			this.setAutoscaleMargin(10);
			this.setTicks(null);
			this.setTickSize(0);
		}
		
		public String getMode() {
			return mode;
		}
		public void setMode(String mode) {
			this.mode = mode;
		}
		public float getMin() {
			return min;
		}
		public void setMin(float min) {
			this.min = min;
		}
		public float getMax() {
			return max;
		}
		public void setMax(float max) {
			this.max = max;
		}
		public int getAutoscaleMargin() {
			return autoscaleMargin;
		}
		public void setAutoscaleMargin(int autoscaleMargin) {
			this.autoscaleMargin = autoscaleMargin;
		}
		public ArrayList<Ticks> getTicks() {
			return ticks;
		}
		public void setTicks(ArrayList<Ticks> ticks) {
			this.ticks = ticks;
		}
		public int getTickSize() {
			return tickSize;
		}
		public void setTickSize(int tickSize) {
			this.tickSize = tickSize;
		}
	}
	
	public class Ticks {
		float XorY;
		String value;
		
		public Ticks(float _XorY, String _value) {
			this.XorY = _XorY;
			this.value = _value; 
		}
	}
	
	

	/**
	 * @param width unit: DP
	 * @param height unit: DP
	 */
	public void setSize(float width, float height) {
		this.size.width = width;
		this.size.height = height;
	}

	// GraphData graphDatas[] = new GraphData[10];
	ArrayList<GraphData> graphDatas = new ArrayList<GraphData>();
	// ArrayList<Graphdata> graphDatas = new ArrayList()<Graphdata>;

	int dataCount = 0;

	public void addData(GraphData data) {
		graphDatas.add(data);
	}

	public void addData(long x, float y) {
		GraphData data = new GraphData(x, y);
		graphDatas.add(data);
	}

	public void removeDataAtIndex(int index) {
		if (index < graphDatas.size()) {
			graphDatas.remove(index);
		}
	}
	
	public void addDataArray(ArrayList<GraphData> _graphDatas, int color, String title) {
		arrayGraphData.add(_graphDatas);
		arrayGraphColor.add(color);
		arrayGraphTitle.add(title);
	}
	

	public void removeAllData() {
		graphDatas = new ArrayList<GraphData>();
	}

	public int DPtoPX(float dp) {
		return Math.round(outMetrics.density * dp);
	}


	/**
	 * @param canvas
	 *            canvas
	 * @param showLine
	 *            라인을 나타낼지 여부
	 * @param showPoint
	 *            지점을 나타낼지 여부
	 */
	public void makeGraph(Canvas canvas, boolean showLine, boolean showPoint) {
		Paint paint = new Paint();

		double minX = Double.MAX_VALUE;
		double minY = Double.MAX_VALUE;
		double maxX = Double.MIN_VALUE;
		double maxY = Double.MIN_VALUE;
		
		/*
		 * 스케일을 잡음
		 */
		// 입력된 데이터의 최소, 최대 x축의 값을 뽑아냄
		for(int j=0; j<arrayGraphData.size(); j++) {
			graphDatas = arrayGraphData.get(j); 
			for (int i = 0; i < graphDatas.size(); i++) {
				double tempX = graphDatas.get(i).x;
				double tempY = graphDatas.get(i).y;
	
	
				if (minX > tempX) {
					minX = tempX;
				}
				if (maxX < tempX) {
					maxX = tempX;
				}
				if (minY > tempY) {
					minY = tempY;
				}
				if (maxY < tempY) {
					maxY = tempY;
				}
			}
		}
		
		if (D) {
			Log.v(TAG, "------------------------------");
			Log.e(TAG, "graphDatas.size():" + graphDatas.size());
			Log.v(TAG, "Input data boundary is");
			Log.v(TAG, "minX:" + minX);
			Log.v(TAG, "maxX:" + maxX);
			Log.v(TAG, "minY:" + minY);
			Log.v(TAG, "maxY:" + maxY);
			Log.v(TAG, "------------------------------");
		}
		
		// 그래프 그려질 범위를 그림
		paint.setAntiAlias(true);
		paint.setColor(Color.rgb(88, 89, 91));
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeWidth(1);
		
		if (D) {
			Log.v(TAG, "------------------------------");
			Log.v(TAG, "Graph Size is");
			Log.v(TAG, "size(w):" + size.width);
			Log.v(TAG, "size(h):" + size.height);
			Log.v(TAG, "Origin of graph is");
			Log.v(TAG, "origin(x):" + origin.x);
			Log.v(TAG, "origin(y):" + origin.y);
			Log.v(TAG, "------------------------------");
		}
		
		//canvas.drawLine(origin.px_x, graphMarginTop, size.px_width, graphMarginTop, paint);
		canvas.drawLine(origin.x, size.height - origin.y + graphMarginTop, size.width, size.height - origin.y + graphMarginTop, paint);
		//canvas.drawRect(origin.px_x, graphMarginTop, size.px_width, size.px_height - origin.px_y + graphMarginTop, paint);
		
		if(axisX.getMin() != Float.NEGATIVE_INFINITY) {
			minX = axisX.getMin();
			canvas.drawText(String.valueOf(minX), 30, 30, paint);
		}
		if(axisX.getMax() != Float.POSITIVE_INFINITY) {
			maxX = axisX.getMax();
		}
		if(axisY.getMin() != Float.NEGATIVE_INFINITY) {
			minY = axisY.getMin();
			axisY.setAutoscaleMargin(0);
		}
		
		/*if(axisY.getMax() != Float.POSITIVE_INFINITY) {
			maxY = axisY.getMax();
			axisY.setAutoscaleMargin(0);
		}*/
		if(maxY < 0.05) {
			maxY = 0.05;
		} else if(maxY < 0.1) {
			maxY = 0.1;
		} else if(maxY < 0.15) {
			maxY = 0.15;
		} else if(maxY < 0.2) {
			maxY = 0.2;
		} else if(maxY < 0.25) {
			maxY = 0.25;
		} else if(maxY < 0.3) {
			maxY = 0.3;
		} else if(maxY < 0.35) {
			maxY = 0.35;
		} else if(maxY < 0.4) {
			maxY = 0.4;
		} else if(maxY < 0.45) {
			maxY = 0.45;
		} else if(maxY < 0.5) {
			maxY = 0.5;
		}
		maxY += 0.001;
		
		
		
		double dataRangeWidth_graph 	= (size.width - origin.x) - 2*axisX.getAutoscaleMargin();
		double dataRangeWidth_data	= maxX - minX;
		double dataRangeHeight_graph 	= (size.height - origin.y) - 2*axisY.getAutoscaleMargin();
		double dataRangeHeight_data	= maxY - minY;
		double scaleX = dataRangeWidth_graph/dataRangeWidth_data;
		double scaleY = dataRangeHeight_graph/dataRangeHeight_data;
		
		double offsetDataX = axisX.getAutoscaleMargin();
		double offsetDataY = axisY.getAutoscaleMargin();
		
		
		paint.setStrokeWidth(1);
		paint.setColor(Color.GRAY);
		
		
		//X축에 표시를 한다.
		//makeAxixX(10, minX, scaleX, canvas);
		
		//Y축에 표시를 한다.
		makeAxixY((int)(5*scaleY), minY, scaleY, canvas, true);		
		
		//X축에 라벨을 작성한다.
		//makeLabelX("날짜", canvas);
		
		//Y축에 라벨을 작성한다.
		//makeLabelY("수분도 (%)", canvas);
		
		
		
		for(int i=0; i<arrayGraphData.size(); i++) {
			graphDatas = arrayGraphData.get(i);
			//라인을 그린다.
			makeLineAtGraph(minX, minY, scaleX, scaleY, offsetDataX, offsetDataY, canvas, arrayGraphColor.get(i));
			
			//점을 찍는다.
			makeTicksX(minX, minY, scaleX, scaleY, offsetDataX, offsetDataY, canvas, arrayGraphColor.get(i));
			
			//Y축에 주선과 보조선을 긋는다
			makeTicksY(minY, maxY, scaleX, scaleY, offsetDataX, offsetDataY, canvas);
			
			//상단에 글씨를 적는다
			makePoint(minX, minY, scaleX, scaleY, offsetDataX, offsetDataY, canvas, arrayGraphColor.get(i));
			
			//하단에 인덱스를 표시한다.
			writeNumberAbovePoint(minX, minY, scaleX, scaleY, offsetDataX, offsetDataY, canvas, arrayGraphColor.get(i));
		}
		
		//legend를 표시
		/*canvas.translate(size.dp_width + origin.px_x +65, 30);

		paint.setStyle(Paint.Style.FILL);
		paint.setColor(Color.argb(230, 0xff, 0xff, 0xff));
		canvas.drawRoundRect(new RectF(0, 0, 90, arrayGraphData.size()*20+10), (float)5, (float)5, paint);
		
		paint.setStyle(Paint.Style.STROKE);
		paint.setStrokeWidth(1);
		paint.setColor(Color.argb(80, 0, 0, 0));
		canvas.drawRoundRect(new RectF(0, 0, 90, arrayGraphData.size()*20+10), (float)5, (float)5, paint);
		
		for(int i=0; i<arrayGraphData.size(); i++) {
			paint.setColor(arrayGraphColor.get(i));
			paint.setStyle(Paint.Style.FILL);
			canvas.drawRect(10, i*20+8, 25, i*20+23, paint);
			
			paint.setColor(Color.BLACK);
			canvas.drawText(arrayGraphTitle.get(i), 30, i*20 + 18, paint);
		}
		canvas.restore();
*/		
	}
	
	private void makeLineAtGraph(double minX, double minY, double scaleX, double scaleY, double offsetDataX, double offsetDataY, Canvas canvas, int color) {
		Paint paint = new Paint();
		paint.setStrokeWidth(2);
		paint.setAntiAlias(true);
		
		for (int i = 0; i < graphDatas.size(); i++) {
			if(color == 0) {
				paint.setColor(Color.rgb(88, 89, 91));
			} else {
				paint.setColor(color);
			}
			
			int pointX = (int) Math.round((graphDatas.get(i).x - minX) * scaleX + offsetDataX);
			//int pointX2 = Math.round((graphDatas.get(i+1).x - minX) * scaleX + offsetDataX);
			int pointY = (int) ((size.height - origin.y) - Math.round((graphDatas.get(i).y - minY) * scaleY + offsetDataY) + graphMarginTop);
			//int pointY2 = (int) ((size.px_height - origin.px_y) - Math.round((graphDatas.get(i+1).y - minY) * scaleY + offsetDataY) + graphMarginTop);
			
			/*Log.e("zmin2", "X:"+pointX);
			Log.e("zmin2", "Y:"+pointY);*/
			
			canvas.drawLine(origin.x + pointX, pointY, origin.x + pointX, size.height - origin.y + graphMarginTop, paint);
		}
	}
	
	/**
	 * 포인트 상단에 해당 점수를 표시한다.
	 * 
	 * @param minX
	 * @param minY
	 * @param scaleX
	 * @param scaleY
	 * @param offsetDataX
	 * @param offsetDataY
	 * @param canvas
	 * @param color
	 */
	private void makePoint(double minX, double minY, double scaleX, double scaleY, double offsetDataX, double offsetDataY, Canvas canvas, int color) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		
		int maxIndex = 0;
		double maxValue = 0;
		for (int i = 0; i < graphDatas.size(); i++) {
			if(maxValue < graphDatas.get(i).y) {
				maxValue = graphDatas.get(i).y;
				maxIndex = i;
			}
		}
		
		for (int i = 0; i < graphDatas.size(); i++) {
			if(color == 0) {
				paint.setColor(Color.rgb(88, 89, 91));
			} else {
				paint.setColor(color);
			}
			
			if(i == maxIndex) {
				paint.setColor(Color.rgb(0xB7, 0x24, 0x27));
			}
			
			int pointX = (int) Math.round((graphDatas.get(i).x - minX) * scaleX + offsetDataX);
			int pointY = (int) ((size.height - origin.y) - Math.round((graphDatas.get(i).y - minY) * scaleY + offsetDataY) + graphMarginTop);
			
			canvas.drawCircle(origin.x + pointX, pointY, 7, paint);
			paint.setColor(Color.WHITE);
			canvas.drawCircle(origin.x + pointX, pointY, 4, paint);
		}
	}
	
	
	private void makeTicksX(double minX, double minY, double scaleX, double scaleY, double offsetDataX, double offsetDataY, Canvas canvas, int color) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		
		for (int i = 0; i < graphDatas.size(); i++) {
			
			//홀수 인덱스는 표시 안한다.
			if(i%2 == 1) {
				continue;
			}
			
			if(color == 0) {
				paint.setColor(Color.rgb(71, 187, 255));
			} else {
				paint.setColor(color);
			}
			
			paint.setTextSize(DPtoPX(11));
			
			int pointX = (int) Math.round((graphDatas.get(i).x - minX) * scaleX + offsetDataX);
			
			int pointY = (int) (size.height - origin.y) + 30 ;
			
			FontMetrics fontMetrics = paint.getFontMetrics();
			
			SimpleDateFormat sFormat = null;
			SimpleDateFormat dFormat = null;
			dFormat = new SimpleDateFormat("M/d a");
			
			if(unitType == MyView.UNIT_DAY) {
				if(new Date((long) graphDatas.get(i).x).getDate() <= 2 || i == 0) {
					sFormat = new SimpleDateFormat("M/d");
					paint.setTextSize(DPtoPX(13));
				} else {
					sFormat = new SimpleDateFormat("d");
					paint.setTextSize(DPtoPX(11));
				}
			} else {
				if(i==0 || new Date(graphDatas.get(i).x).getHours() == 0
						|| new Date(graphDatas.get(i).x).getHours() == 1
						|| new Date(graphDatas.get(i).x).getHours() == 12
						|| new Date(graphDatas.get(i).x).getHours() == 13) {
					sFormat = new SimpleDateFormat("h");
				} else {
					sFormat = new SimpleDateFormat("h");
				}
			}
			
			String text = sFormat.format(new Date((long) graphDatas.get(i).x));
			String text_month_day = dFormat.format(new Date((long) graphDatas.get(i).x));
			
			float textWidth = paint.measureText(text);
			float textWidth_month_day = paint.measureText(text_month_day);
			
			float topMargin_xTicks = DPtoPX(5);
			/*if(i%2 == 0) {
				topMargin_xTicks = DPtoPX(10);
			}*/

			if(i == -1) {	//원래는 i==0
				//왼쪽정렬
				canvas.drawText(text, origin.x + pointX, pointY - (fontMetrics.ascent + fontMetrics.descent)*2 + topMargin_xTicks, paint);
			} else if((i == 0
					|| new Date(graphDatas.get(i).x).getHours() == 0
					|| new Date(graphDatas.get(i).x).getHours() == 1
					|| new Date(graphDatas.get(i).x).getHours() == 12
					|| new Date(graphDatas.get(i).x).getHours() == 13
					) && unitType == MyView.UNIT_10MIN) {
				
				canvas.drawText(text, origin.x + pointX - textWidth/2, pointY - (fontMetrics.ascent + fontMetrics.descent)*2 + topMargin_xTicks, paint);
				canvas.drawText(text_month_day, origin.x + pointX - textWidth_month_day/2, pointY - (fontMetrics.ascent + fontMetrics.descent)*2 + topMargin_xTicks + DPtoPX(11), paint);
			}
			else if(i == graphDatas.size()-1) {
				//오른쪽 정렬
				canvas.drawText(text, origin.x + pointX - textWidth, pointY - (fontMetrics.ascent + fontMetrics.descent)*2 + topMargin_xTicks, paint);
			} else {
				//가운데 정렬
				canvas.drawText(text, origin.x + pointX - textWidth/2, pointY - (fontMetrics.ascent + fontMetrics.descent)*2 + topMargin_xTicks, paint);
			}
			
			//숫자 위까지 내려오는 짧은 선을 긋는다
			canvas.drawLine(origin.x + pointX, size.height - origin.y + graphMarginTop, origin.x + pointX, pointY + topMargin_xTicks, paint);
			/*
			canvas.drawCircle(origin.px_x + pointX, pointY, 8, paint);
			paint.setColor(Color.WHITE);
			canvas.drawCircle(origin.px_x + pointX, pointY, 5, paint);*/
		}
	}
	
	private void makeTicksY(double minY, double maxY, double scaleX, double scaleY, double offsetDataX, double offsetDataY, Canvas canvas) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		
		float startX = origin.x;
		float stopX = size.width;
		
		float startY = 0, stopY = 0;
		
		final float textSize_common = DPtoPX(11);
		final float textSize_main = DPtoPX(12);
		float textSize = 0;
		
		for (double i=0.0; i< maxY; i+= 0.01) {
			//가로 선을 긋는다.
			if((int)Math.round(i*100)%5 == 0) {
				paint.setColor(Color.rgb(0xAA, 0xAA, 0xAA));
				paint.setStrokeWidth(2);
				DashPathEffect dathPath = new DashPathEffect(new float[] { 3, 3 }, 1);
				paint.setPathEffect(dathPath);
				textSize = textSize_main;
			} else {
				paint.setColor(Color.rgb(0xCC, 0xCC, 0xCC));
				paint.setStrokeWidth(1);
				DashPathEffect dathPath = new DashPathEffect(new float[] { 3, 3 }, 1);
				paint.setPathEffect(dathPath);
				textSize = textSize_common;
			}
			startY = stopY = ((size.height - origin.y) - Math.round((i - minY) * scaleY + offsetDataY) + graphMarginTop);
			canvas.drawLine(startX, startY, stopX, stopY, paint);
			
			
			//숫자를 입력한다.
			paint.setPathEffect(null);
			paint.setTextSize(textSize);
			FontMetrics fontMetrics = paint.getFontMetrics();
			
			String text = String.format("%.2f", (float)i);
			float textWidth = paint.measureText(text);
			
			canvas.drawText(text, origin.x - textWidth - DPtoPX(5), startY - (fontMetrics.ascent + fontMetrics.descent) - textSize/3, paint);
		}
	}
	
	/**
	 * X축에 데이터의 인덱스를 표기한다. 
	 * (월간일 경우 1, 2, 3, 4, 5)
	 * (일간일 경우 00:00, 00:10, 00:20, 00:30)
	 * 
	 * @param minX
	 * @param minY
	 * @param scaleX
	 * @param scaleY
	 * @param offsetDataX
	 * @param offsetDataY
	 * @param canvas
	 * @param color
	 */
	private void writeNumberAbovePoint(double minX, double minY, double scaleX, double scaleY, double offsetDataX, double offsetDataY, Canvas canvas, int color) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		
		if(color == 0) {
			paint.setColor(Color.rgb(71, 187, 255));
		} else {
			paint.setColor(color);
		}
		
		int maxIndex = 0;	//가장 큰 Y값을 갖는 Index
		double maxValue = 0;
		for (int i = 0; i < graphDatas.size(); i++) {
			if(maxValue < graphDatas.get(i).y) {
				maxValue = graphDatas.get(i).y;
				maxIndex = i;
			}
		}
		
		int pointX = (int) Math.round((graphDatas.get(maxIndex).x - minX) * scaleX + offsetDataX);
		int pointY = (int) ((size.height - origin.y) - Math.round((graphDatas.get(maxIndex).y - minY) * scaleY + offsetDataY) + graphMarginTop - 20);
		
		paint.setTextSize(DPtoPX(18));
		FontMetrics fontMetrics = paint.getFontMetrics();
		
		String text = String.format("%.3f",(float)(Math.round(graphDatas.get(maxIndex).y * 1000f) / 1000f)) + "%";
		
		float textWidth = paint.measureText(text);
		
		float startX = origin.x + pointX - textWidth/2;
		
		//왼쪽 밖으로 벗어나는 경우
		if(startX < origin.x + DPtoPX(5)) {
			startX = origin.x + DPtoPX(5);
		}
		//오른쪽 밖으로 벗어나는 경우
		if(size.width - textWidth - DPtoPX(5) < startX) {
			startX = size.width - textWidth - DPtoPX(5);
		}
		
		canvas.drawText(text, startX, pointY - (fontMetrics.ascent + fontMetrics.descent) / 2 - DPtoPX(5), paint);
		/*
		canvas.drawCircle(origin.px_x + pointX, pointY, 8, paint);
		paint.setColor(Color.WHITE);
		canvas.drawCircle(origin.px_x + pointX, pointY, 5, paint);*/
	
	}
	
	
	private void makeAxixX(int space, float minX, float scaleX, Canvas canvas) {
		int spaceX = space;
		Paint paint = new Paint();
		paint.setColor(Color.GRAY);
		paint.setStrokeWidth(1);
		
		for(int i=0; i*spaceX <= size.width - origin.x; i++) {
			if(i%5 ==0) {
				canvas.drawLine(origin.x + i*spaceX, size.height - origin.y + graphMarginTop, origin.x+i*spaceX, size.height - origin.y + 10 + graphMarginTop, paint);
				paint.setTextAlign(Align.CENTER);
				paint.setAntiAlias(true);
				canvas.drawText(String.format("%.1f", minX + ((i*spaceX - axisX.getAutoscaleMargin())/scaleX)), origin.x+i*spaceX, size.height-origin.y+25 + graphMarginTop, paint);
				paint.setAntiAlias(false);
				continue;
			}
			
			canvas.drawLine(origin.x + i*spaceX, size.height - origin.y + graphMarginTop, origin.x+i*spaceX, size.height - origin.y + 5 + graphMarginTop, paint);
		}
	}
	
	private void makeAxixY(int space, double minY, double scaleY, Canvas canvas, boolean Grid) {
		int spaceY = space;
		Paint paint = new Paint();
		paint.setColor(Color.rgb(0xDD, 0xDD, 0xDD));
		paint.setStrokeWidth(1);
		
		//int pointY = (int) ((size.height - origin.y) - Math.round(0 - minY) * scaleY + offsetDataY) + graphMarginTop);
		
		float startY = (float)((size.height - origin.y) - Math.round(0 - minY) * scaleY) + graphMarginTop ;
		
		canvas.drawLine(origin.x, startY, origin.x, 0, paint);
	}
	
	/**
	 * @param title X축의 이름
	 * @param canvas Canvas
	 * @param paint Paint
	 */
	private void makeLabelX (String title, Canvas canvas) {
		String labelX = title;
		Paint paint = new Paint();
		
		paint.setAntiAlias(true);
		paint.setTextAlign(Align.CENTER);
		paint.setTextSize(18);
		paint.setColor(Color.rgb(14, 132, 204));
		
		canvas.drawText(labelX, (size.width + origin.x)/2, size.height - origin.y + 50 + graphMarginTop, paint);
	}
	
	/**
	 * @param title Y축의 이름
	 * @param canvas Canvas
	 * @param paint Paint
	 */
	private void makeLabelY (String title, Canvas canvas) {
		String labelY = title;
		Paint paint = new Paint();
		
		paint.setAntiAlias(true);
		paint.setTextAlign(Align.CENTER);
		paint.setTextSize(18);
		paint.setColor(Color.rgb(14, 132, 204));
		
		canvas.translate(origin.x - 50, (size.height - origin.y)/2 + graphMarginTop);
		canvas.rotate(-90);
		canvas.drawText(labelY, 0, 0, paint);
		canvas.restore();
	}

	
	public void setColorLine(int color) {
		colorLine = color;
	}
	
	public void setColorPoint(int color) {
		colorPoint = color;
	}
}
